<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>bar</title>
  <style type="text/css">
    #bar {
      border-radius: 5px;
      border: 1px solid #cccccc;
    }
  </style>
</head>

<body>
  <canvas id="bar" width="800" height="500"></canvas>
  <script type="text/javascript">
    (function () {
      let canvas = null;
      let ctx = null;
      let width = 0;
      let height = 0;
      let widthRadius = 0;
      let heightRadius = 0;
      // 加载完成后执行事件
      let endedEvent = new Event('ended');
      let XYAxisColor = '#000000';
      let barColor = '#6495ED';
      let labelColor = '#000000'
      // X轴Y轴的高度和宽度
      let XSize = 0;
      let XFullSize = 0;
      let YSize = 0;

      // 最大的柱子距离顶部的距离
      let maxBarTop = 10;

      // bar的宽度
      let barWidth = 0;
      // bar的数量
      let barCount = 0;
      // bar的间隔
      let barGap = 20;

      // Y轴 label数量
      let YCount = 10;

      // 数据
      let data = [
        { value: 1000, label: "苏宁易购" },
        { value: 5000, label: "东方甄选" },
        { value: 1000, label: "淘宝精选" },
        { value: 10000, label: "京东商城" },
        { value: 1000, label: "拼 多 多" },
        { value: 3000, label: "亚 马 逊" }
      ]

      function start() {
        init();
        skeleton()
        rander();
        bindEvent()
      }

      function init() {
        canvas = document.getElementById('bar');
        ctx = canvas.getContext('2d');
        // canvas.setAttribute('width', (document.documentElement.clientWidth || document.body.clientWidth) - 60);
        width = canvas.clientWidth;
        height = canvas.clientHeight;
        widthRadius = width / 2;
        heightRadius = height / 2;
        XFullSize = height;
        XSize = height * 0.6;
        YSize = width * 0.6;
      }
      // 绘制骨架相关
      function skeleton() {
        // 初始画布背景
        ctx.fillStyle = '#ffffff'
        ctx.fillRect(0, 0, width, height);
        // 初始化绘制点 左下角+padding 20px
        ctx.beginPath();
        // 预留X轴和Y周的label位置
        ctx.translate(80, height - 80);
        // 绘制X轴
        ctx.strokeStyle = XYAxisColor
        ctx.lineWidth = 2;
        ctx.moveTo(0, 0)
        ctx.lineTo(0, -XSize);
        ctx.stroke();
        ctx.fillStyle = XYAxisColor;
        ctx.font = 'bold 15px cursive';
        ctx.fillText('Y', -2.5, -XSize - 5);
        // 绘制Y轴
        ctx.beginPath()
        ctx.moveTo(0, 0);
        ctx.lineTo(YSize, 0);
        ctx.stroke();
        ctx.fillStyle = XYAxisColor;
        ctx.font = 'bold 15px cursive';
        ctx.fillText('X', YSize + 2.5, 0 + 2.5);
      }

      // 渲染数据
      function rander() {
        barCount = data.length
        // 总宽度/总量 = barwidth
        barWidth = parseInt(YSize / barCount - barGap);

        // 数据中的最大值
        let maxVal = data.reduce((prev, item) => {
          return Math.max(prev, item.value);
        }, 0)

        // 平均每一份多少px
        let avg = (XSize - maxBarTop) / maxVal;
        data.forEach((item, index, arr) => {
          ctx.beginPath();
          ctx.fillStyle = barColor;
          // +1 是为了每次都增加一个间隔
          ctx.fillRect(((index + 1) * barGap) + (index * barWidth), 0, barWidth, -parseInt(avg * item.value));
          ctx.beginPath();
          ctx.textAlign = "left";
          ctx.fillText(`${item.value}`, ((index + 1) * barGap) + (index * barWidth), -parseInt(avg * item.value + 10))
        })

        // 绘制XY轴label
        data.forEach((item, index, arr) => {
          ctx.beginPath();
          ctx.fillStyle = labelColor;
          ctx.fillText(`${item.label}`, ((index + 1) * barGap) + (index * barWidth), 20)
        })

        for (let index = 0; index < YCount; index++) {
          // （平均每条数据中的1占用几个Y轴PX）*（最高值/10个点）
          let yLabelHeight = (XSize / maxVal) * parseInt((maxVal / YCount));
          ctx.beginPath();
          ctx.strokeStyle = labelColor;
          ctx.textAlign = "center";
          ctx.moveTo(1, -(index * yLabelHeight));
          if (!index || index % 2 === 0) {
            ctx.lineTo(-20, -(index * yLabelHeight))
            ctx.fillText(index * parseInt((maxVal / YCount)), -40, -(index * yLabelHeight));
          } else {
            ctx.lineTo(-10, -(index * yLabelHeight))
            ctx.fillText(index * parseInt((maxVal / YCount)), -40, -(index * yLabelHeight));
          }
          ctx.stroke();

          ctx.beginPath();
          if (index == YCount - 1) {
            console.log('最后一个')
          }
        }
      }

      function bindEvent() {
        canvas.addEventListener('ended', (ev) => {
          console.log(ev);
        }, false);
      }
      start()
    })()
  </script>
</body>

</html>